<?php
Loader::import('pspframework.helpers.Helper');
class View extends Object {

	public $base = null;
	
	public $here = null;

	public $name = null;

	public $action = null;

	public $params = array();

	public $passedArgs = array();

	public $data = array();

	public $helpers = array();

	public $MissingviewFilename = null;	
	
	public $viewFilename = null;	

	public $viewVars = array();
	
	public $viewRoot = null;
	
	public $viewPath = null;	

	public $viewCompiledPath = null;

	public $viewViewsmanagesPath = null;
	
	public $viewWebrootPath = null;		

	public $ext = '.html';

	public $subDir = null;	

	public $validationErrors = array();

	public $loaded = array();
	
	public $_psptags = null;	

	public $modelScope = false;

	public $model = null;

	public $association = null;

	public $field = null;

	public $fieldSuffix = null;

	public $output = false;

	public $__passedVars = array(
		'viewVars', 'action', 'ext', 'base', 'webroot',
		'helpers', 'here', 'name', 'params', 'data', 
		'passedArgs', 'subDir'
	);

	public $__paths = array();

	public $activePaths = array();	
	
	public $IsActiveBase = true;		
	
	public $controller = null;
	
	public $IsloadHelperAndApphelper = false;
	
	public $_PspLayoutCount = 0;
	
	public $_SelectCache = array();
	
	public function __construct(&$controller, $register = true) {
		if (is_object($controller)) {
			$count = count($this->__passedVars);
			for ($j = 0; $j < $count; $j++) {
				$var = $this->__passedVars[$j];
				$this->{$var} = $controller->{$var};
			}
			$this->controller = $controller;
		}
		parent::__construct();
		if ($register) {
			ClassRegistry::addObject('view', $this);
		}
	}
	
	public function element($name, $params = array(), $loadHelpers = false) {	
		$file = $key = null;
		$paths = $this->_paths('views');
		foreach ($paths as $path) {
			if (file_exists($path . DS .'elements' . DS . $name . $this->ext)) {
				$file = $path . DS .'elements' . DS . $name . $this->ext;
				break;
			}
		}
		if (is_file($file)) {
			$params = array_merge_recursive($params, $this->loaded);			
			$element = $this->_render($file, array_merge($this->viewVars, $params), $loadHelpers);
			return $element;
		}
		$file = $paths[0] . 'elements' . DS . $name . $this->ext;
		if (Param::read() > 0) {
			return "Not Found Element File: " . $file;
		}
	}

	public function render($action = null,$type = null) {
		$out = null;
		if (empty($action)) {
		    $action = $this->action;
		}
		if($type !==null) {
			$this->subDir = $type;					
		}
		if ($action !== false ) {	    
			$this->compiled($action);
		} 		
		if ($action !== false && $viewFileName = $this->_getViewFileName($action,'compiled')) {	
			$out = $this->_render($viewFileName, $this->viewVars);
		}
		return $out;
	}

	public function compiled($action) {	
	    $viewFileName = $this->_getViewFileName($action);
		$CviewFileName = $this->_getViewFileName($action,'compiled');				
		$MviewFileName = $this->_getViewFileName($action,'viewsmanages');		
		if ( Param::read('UserDebug.view')==true || file_exists($CviewFileName) === false  || (@filemtime($viewFileName) > @filemtime($CviewFileName)) || (@filemtime($MviewFileName) > @filemtime($CviewFileName))){
		    $tempfilename = '';				
		    if(is_file($MviewFileName)/* && (@ filemtime($MviewFileName) > @ filemtime($CviewFileName) )*/){			
		        $tempfilename = $MviewFileName;				   			
			} else {
			    if (!is_file($viewFileName)){
					exit("Not Found view File: " . $this->MissingviewFilename);
			    }
		        $tempfilename = $viewFileName;		
			}            
			$out = '';
			if (!($out = file_get_contents($tempfilename))) {
				return false;
			}
			Loader::import('pspframework.views.Compile');
			$compile = new Compile($this,$this->controller);
			$out = $compile->_template($out);		
			if (!file_exists($CviewFileName)) {
                $CviewFileName = str_replace(array('\\','/'), DS ,$CviewFileName);
				$temp = explode(DS, $CviewFileName);
				array_pop( $temp );
                $tempFileDir = implode( DS.'' , $temp );
				get_dir($tempFileDir);
			}
			if (!file_put_contents($CviewFileName, $out)) {
				return false;
			}				
            return true; 
		}
		return false;
	}	
	
	public function TagsActive($activetime,$activebefore,$activeperiod,$activeafter) {        
        if($activetime) {
		    $temp = $temp1 = array();	
		    $temp = explode(",",$activetime);			
            $temp = filterEmptyVar($temp);
			$now_time = time();		
		    $before_time = strtotime($temp[0]);
		    $after_time = strtotime($temp[1]);
					
			if(($before_time>$now_time)&&$activebefore)	{
			   return $this->__GoActive($activebefore,'before');
			}
			if(($after_time<$now_time)&&$activeafter){
			   return $this->__GoActive($activeafter,'after');
			}			
			if(($after_time>=$now_time&&$before_time<=$now_time)&&activeperiod)	{
			   return $this->__GoActive($activeperiod,'period');
			}		 
	    }else{
			if($activebefore){
			   return  $this->__GoActive($activebefore,'before');
			}
			if($activeafter){
			   return $this->__GoActive($activeafter,'after');
			}	      
	    } 
    }
	
	public function __GoActive($app, $active) {
	    $file = $this->viewRoot. DS .'active'. DS .$active. DS .$app.'.active.'.$active.'.php';		

		if($this->IsActiveBase) {
            Loader::import('pspframework.utils.ActiveBase');
			$this->IsActiveBase = false;
		}		
	    if(!isset($this->activePaths[$file])) {	
		    include( $file);
			$this->activePaths[$file] = 1 ;
		}
		$class_name = ucfirst($app) . 'Active';
		$appbody = new $class_name();	
		if ($app && $app {0} != '_' && method_exists($appbody, $app)) {
			$return = $appbody-> $app( $this );
		} else {
			exit ('Missing Active Action');
		}		
		return $return;		
	}


	public function  TagsCache($dir='',$type=null) {
      static $_cache;
       $temp = array();
		if (!isset($_cache[$dir])) {
			if (!is_file($dir)) 
			{
				return array();
			}
			$temp = include($dir);
			if($type == 'tags') {
			    $_cache[$dir] = $temp['data'];
			} else {
			    $_cache[$dir] = $temp;
			}			
		}
		return $_cache[$dir];
    }
	

	public function TagsModel($varname,$tb = array()) {
	    if(!$varname) {
		    return array();
		}
        $tb = $tb + array('table' => '', 'fields' => '*',
					'conditions' => '',	'order' => '',
					'limit' => '', 'url' => '',
					'page' => 1,'plist' => 6,'ispage'=>false,
					'startPage' => false,'DbConfig' => null
					) ; 
		if($tb['ispage']) {			
			$tpage = intval(Request::get_args("page"));			
			if($tpage>1) {
				$tb['page'] = $tpage;
			}
        }else {
            $tb['page'] = 1;
        }	
        $isdistinct = '';
		if($tb['isdistinct']) {
            $isdistinct = ' distinct ';
		}        	
	    if($DbConfig ===null) {
		    $DbConfig = 'default';
		}					
        $key = $varname.'_'.$tb['page'].'_'.crc32($tb['table'].$tb['fields'].$tb['conditions'].$tb['order'].$tb['limit'].$tb['DbConfig'].$tb['startPage']);					
		$sources = Cache::read($key, '_psp_tags_');
		if (!empty($sources)) {
		    $this->viewVars = $sources + $this->viewVars;		
            return true;
		}	
        extract($tb, EXTR_SKIP);
        ($conditions=='')?$conditions = '':$conditions = '  WHERE  '.$conditions;		
	    $db =& ConnectionManager::getDataSource($DbConfig);
 		$data = array();
		if($startPage) {
            $page = empty($page) ? 1 : intval($page);
			$plist = empty($plist) ? 6 : intval($plist);			
		    $data1 = $db->fetchRow("SELECT COUNT(*) AS count  FROM {$table} {$conditions} ");
		    $totalnum = $data1[0]['count'];		
	        $totalpage=intval(@ceil($totalnum/$limit));
	        $nextpage=$page+1;
	        $uppage=$page-1;		 
	        if($nextpage>$totalpage){
		        $nextpage=$totalpage;
	        }		 
	        if($uppage<1){
		        $uppage=1;
	        }
	        $s=$page-3;
	        if($s<1){
		       $s=1;
	        }
	        $b=$s + $plist;
	        if($b>$totalpage){
		        $b=$totalpage;
	        }			
	        for($j=$s;$j<=$b;$j++){
		        if($j==$page) {
			        $data[$varname]['page']['current']['num'] = $j;
					$data[$varname]['page']['current']['url'] = "$url&page=$j";
		        } else {      
			        $data[$varname]['page']['plist'][$j] = "$url&page=$j";			         
		        }
	        }		  
            if(!isset($data[$varname]['page']['current'])){
		        $data[$varname]['page']['current']['num'] =1;
		        $data[$varname]['page']['current']['url'] = "$url&page=1"; 
		    }	  
		    $start = ($page-1) * $limit;		  	  
		    $data[$varname]['page']['head'] =  "$url&page=1";
		    $data[$varname]['page']['prevPage'] = "$url&page=$uppage";
		    $data[$varname]['page']['nextPage'] = "$url&page=$nextpage";
		    $data[$varname]['page']['foot'] = "$url&page=$totalpage";
		    $data[$varname]['page']['pageCount'] = $totalpage;
		    $data[$varname]['page']['total'] = $totalnum;
		}else {
		    $start = 0;
		}	
        // 排序(ORDER BY) desc表示倒序,asc表示正序(这个是默认的) 
        $order && $order = ' ORDER BY ' . $order . ' ';
        $limit && $limit = " LIMIT {$start},{$limit} ";
		$query = "SELECT {$isdistinct} {$fields} FROM {$table} {$conditions} {$order} {$limit}";
		$data[$varname]['data'] = $db->QueryAll($query);
		Cache::write($key, $data, '_psp_tags_');		
		$this->viewVars = $data + $this->viewVars;
	}	
	

	public function _triggerHelpers($callback) {
		if (empty($this->loaded)) {
			return false;
		}
		$helpers = array_keys($this->loaded);
		foreach ($helpers as $helperName) {
			$helper =& $this->loaded[$helperName];
			if (is_object($helper)) {
				if (is_subclass_of($helper, 'Helper')) {
					$helper->{$callback}();
				}
			}
		}
	}


	public function getVars() {
		return array_keys($this->viewVars);
	}


	public function getVar($var) {
		if (!isset($this->viewVars[$var])) {
			return null;
		} else {
			return $this->viewVars[$var];
		}
	}

	public function _url($url,$isselect=true) {
        return Router::url($url,$isselect);
	}
	
	public function _webroot($url,$isall=true) {	    
		$url = ltrim(ltrim($url,'/'),'\\');
	    if ($isall) {
		    return $this->base . str_replace(array(DS),array('/') , $this->viewWebrootPath).'/'.$url;
		} else {
		    return str_replace(array(DS),array('/') , $this->viewWebrootPath) .'/'.$url;
		}        
	}
	
	public function _upfile($url,$isall=true) {	   
        return Request::UpfileDir($url,$isall);     
	}
		
	
	public function set($one, $two = null) {
		$data = null;
		if (is_array($one)) {
			if (is_array($two)) {
				$data = array_combine($one, $two);
			} else {
				$data = $one;
			}
		} else {
			$data = array($one => $two);
		}
		if ($data == null) {
			return false;
		}
		$this->viewVars = $data + $this->viewVars;
	}


	public function error($code, $name, $message) {
		header ("HTTP/1.1 {$code} {$name}");
		print ($this->_render(
			$this->viewRoot . DS .'errors' . DS . 'error'.$code.$this->ext,
			array('code' => $code, 'name' => $name, 'message' => $message)
		));
	}


	public function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
		$loadedHelpers = array();
		if ($this->helpers != false && $loadHelpers === true) {
			$loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
			$helpers = array_keys($loadedHelpers);
			for ($i = count($helpers) - 1; $i >= 0; $i--) {
				$name = 'H_'.$helpers[$i];
				$helper =& $loadedHelpers[$helpers[$i]];
				if (!isset($___dataForView[$name])) {
					${$name} =& $helper;
				}
				$this->loaded[$helpers[$i]] =& $helper;
				$this->{$helpers[$i]} =& $helper;
			}
			$this->_triggerHelpers('beforeRender');
			unset($name, $loadedHelpers, $helpers, $i , $helper);
		}
		extract($___dataForView, EXTR_SKIP);
		ob_start();		
		if (Param::read() > 0) {
			include ($___viewFn);
		} else {
			@include ($___viewFn);
		}
		if ($loadHelpers === true) {
			$this->_triggerHelpers('afterRender');
		}
		$out = ob_get_clean();
		return $out;
	}


	public function &_loadHelpers(&$loaded, $helpers, $parent = null) {
		foreach ($helpers as $i => $helper) {
			$options = array();
			if (!is_int($i)) {
				$options = $helper;
				$helper = $i;
			}
			$helperCn = $helper . 'Helper';
			if (!isset($loaded[$helper])) {
			    if ($this->IsloadHelperAndApphelper ==false) {
				    if (!class_exists('Helper')) {
					    Loader::import('pspframework.helpers.helper');	
				    }
				    if (!class_exists('AppHelper')) {
					    Loader::import('helpers.app');
				    }
					$this->IsloadHelperAndApphelper = true;
                }					
				if (!class_exists($helperCn)) {
				    Loader::import('helpers.'.strtolower($helper));
				}
				$loaded[$helper] =& new $helperCn($options);				
				$vars = array('base', 'webroot', 'here', 'params', 'action', 'data', 'theme', 'plugin', 'viewWebrootPath');
				$c = count($vars);
				for ($j = 0; $j < $c; $j++) {
					$loaded[$helper]->{$vars[$j]} = $this->{$vars[$j]};
				}
				if (!empty($this->validationErrors)) {
					$loaded[$helper]->validationErrors = $this->validationErrors;
				}
				if (is_array($loaded[$helper]->helpers) && !empty($loaded[$helper]->helpers)) {
					$loaded =& $this->_loadHelpers($loaded, $loaded[$helper]->helpers, $helper);
				}
			}
			if (isset($loaded[$parent])) {
				$loaded[$parent]->{$helper} =& $loaded[$helper];
			}
		}
		return $loaded;
	}
	

	public function _getViewFileName($name = null,$type = null) {
		$subDir = null;
		if ($type === null) {
			$type = 'views';
		}
		if($type == 'views') {
		    $viewVar = 'viewPath';		
		} else {
		    $viewVar = 'view'.ucfirst($type).'Path';	
		}
		if (isset($this->{$viewVar})) {
            return $this->{$viewVar}; 
		}		
		if (!is_null($this->subDir)) {
			$subDir = $this->subDir . DS;
		}
		if ($name === null) {
			$name = $this->action;
		}
		$name = str_replace(array('/','.'), array(DS,''), $name);				
		$name = trim($name, DS);
		$name =  $subDir . strtolower($name);	
		$paths = $this->_paths();		
		$ext = $this->ext;	
		foreach ($paths[$type] as $key => $path) {		
			if ($type == 'views' && file_exists($path  . DS .  $name . $ext)) {
  			    $this->viewFilename =  $name . $ext;
                $this->viewRoot = $path ;			
                $this->viewPath = $path  . DS .  $name . $ext;
	            $this->viewCompiledPath = $paths['compiled'][$key] . DS .  $name . '.php';				
	            $this->viewViewsmanagesPath = $paths['viewsmanages'][$key] . DS .  $name . $ext;
	            $this->viewWebrootPath = $paths['webroot'][$key];					
				return $this->viewPath;
			}
		}
        $this->MissingviewFilename = $name . $ext;		
		return false;
	}


	public function _paths($type = null) {	
		if ($type && isset($this->__paths[$type])) {
			return $this->__paths[$type];
		}	
		if (!empty($this->__paths)) {
			return $this->__paths;
		}
		$paths = array();
        $viewStyle = Param::read('View.style');
        $viewCss = Param::read('View.css'); 
        $viewWebroot = Param::read('View.assetpath'); 		
        if( Request::$params['prefixes'] ) {
            $viewStyle = Request::$params['prefixes']; 
        } 
		$compiledStyle = 'views';
		if (isset($this->controller->C_session) && $this->controller->C_session->check('TagsViewStartOrStop')) {
		    $compiledStyle = 'viewsmanages';
		}		
        if(isset(Request::$params['plugin']) && !empty(Request::$params['plugin'])) {
			$plugins_root = APP_ROOT . Param::read('plugins.path')  . DS . Request::$params['plugin'];	
			$framework_plugins_root = FRAMEWORK_ROOT  . DS . 'plugins'  . DS . Request::$params['plugin'];	
            if( is_dir($plugins_root) && file_exists($plugins_root) ) {
				$cur_plugins_root = $plugins_root;
				$compiled_path = 'app_plugins';		
                $paths['webroot'][] =  DS .'plugins' . DS .  Request::$params['plugin'] . DS . 'webroot' . DS. $viewStyle . DS. $viewCss ;					
		    }else if( is_dir($framework_plugins_root ) && file_exists($framework_plugins_root ) ) {	
				$cur_plugins_root = $framework_plugins_root;
				$compiled_path = 'psp_plugins';
                $paths['webroot'][] =  $viewWebroot . DS . 'psp_plugins' . DS .  Request::$params['plugin'] . DS. $viewStyle . DS. $viewCss ;					
			}
            $paths['views'][] = $cur_plugins_root . DS .  'views'  . DS . $viewStyle  ;
           	$paths['compiled'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'compiled' . DS . $compiledStyle . DS . $compiled_path . DS . Request::$params['plugin'] . DS. $viewStyle;
            $paths['viewsmanages'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'viewsmanages' . DS . $compiled_path . DS . Request::$params['plugin'] . DS. $viewStyle;	
		}else {
		    $compiled_path = 'app';	
		}
        $paths['webroot'][] =  $viewWebroot . DS. $viewStyle . DS. $viewCss ;
        $paths['webroot'][] =  $viewWebroot  . DS . 'psp_framework' . DS. $viewStyle . DS. $viewCss ;		
		$paths['views'][] = APP_ROOT . Param::read('View.path') . DS . $viewStyle  ;
		$paths['compiled'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'compiled' . DS . $compiledStyle . DS . $compiled_path . DS . $viewStyle;	
		$paths['viewsmanages'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'viewsmanages' . DS . $compiled_path . DS . $viewStyle;
        if(Request::$params['prefixes']) {
			$paths['views'][] = FRAMEWORK_ROOT  . DS . 'lib' . DS .  'views' . DS . Request::$params['prefixes'];
			$paths['compiled'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'compiled' . DS . $compiledStyle . DS . 'pspframework' . DS . Request::$params['prefixes'];			
			$paths['viewsmanages'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'viewsmanages' . DS . 'pspframework' . DS . Request::$params['prefixes'];
	    } else {
			$paths['views'][] = FRAMEWORK_ROOT  . DS . 'lib' . DS .  'views' . DS . 'default';
			$paths['compiled'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'compiled' . DS . $compiledStyle . DS . 'pspframework' . DS . 'default';		
			$paths['viewsmanages'][] = APP_ROOT  . DS . 'app' . DS .  'temp' . DS . 'viewsmanages' . DS . 'pspframework' . DS . 'default';
        }		
		$this->__paths = $paths;
		if ($type && isset($this->__paths[$type])) {
			return $this->__paths[$type];
		}			
		return $this->__paths;		
	}
}
